/**
 * 时间轴系统核心模块
 * 处理时间轴管理、轨道控制、关键帧编辑等
 */

import type { Keyframe } from '../engine'

// 轨道类型枚举
export enum TrackType {
  TRANSFORM = 'transform',
  POSITION = 'position',
  SCALE = 'scale',
  ROTATION = 'rotation',
  OPACITY = 'opacity',
  COLOR = 'color',
  AUDIO = 'audio',
  CUSTOM = 'custom'
}

// 轨道状态枚举
export enum TrackState {
  ACTIVE = 'active',
  INACTIVE = 'inactive',
  MUTED = 'muted',
  SOLO = 'solo'
}

// 时间轴轨道接口
export interface TimelineTrack {
  id: string
  name: string
  type: TrackType
  layerId?: string
  parentId?: string
  children: string[]
  visible: boolean
  locked: boolean
  muted: boolean
  solo: boolean
  state: TrackState
  color: string
  height: number
  expanded: boolean
  keyframes: Keyframe[]
  metadata: Record<string, any>
}

// 时间轴标记接口
export interface TimelineMarker {
  id: string
  name: string
  time: number
  type: 'scene' | 'action' | 'dialogue' | 'effect' | 'custom'
  color: string
  description?: string
  metadata: Record<string, any>
}

// 时间轴区域接口
export interface TimelineRegion {
  id: string
  name: string
  startTime: number
  endTime: number
  trackIds: string[]
  color: string
  locked: boolean
  metadata: Record<string, any>
}

// 时间轴配置接口
export interface TimelineConfig {
  duration: number
  frameRate: number
  timeUnit: 'seconds' | 'frames'
  snapToGrid: boolean
  gridSize: number
  autoScroll: boolean
  showRuler: boolean
  showGrid: boolean
  zoomLevel: number
  viewportStart: number
  viewportEnd: number
}

// 时间轴状态接口
export interface TimelineState {
  currentTime: number
  playbackState: 'playing' | 'paused' | 'stopped'
  loop: boolean
  speed: number
  selectedTracks: string[]
  selectedKeyframes: string[]
  selectedMarkers: string[]
  selectedRegions: string[]
  clipboard: {
    type: 'keyframes' | 'tracks' | 'markers'
    data: any[]
  }
}

// 时间轴管理器类
export class TimelineManager {
  private tracks = new Map<string, TimelineTrack>()
  private markers = new Map<string, TimelineMarker>()
  private regions = new Map<string, TimelineRegion>()
  private config: TimelineConfig
  private state: TimelineState
  private trackOrder: string[] = []
  private callbacks = {
    onTrackAdd: [] as Array<(track: TimelineTrack) => void>,
    onTrackRemove: [] as Array<(trackId: string) => void>,
    onTrackUpdate: [] as Array<(track: TimelineTrack) => void>,
    onKeyframeAdd: [] as Array<(trackId: string, keyframe: Keyframe) => void>,
    onKeyframeRemove: [] as Array<(trackId: string, keyframeId: string) => void>,
    onKeyframeUpdate: [] as Array<(trackId: string, keyframe: Keyframe) => void>,
    onTimeChange: [] as Array<(time: number) => void>,
    onSelectionChange: [] as Array<(selection: any) => void>
  }

  constructor(config: Partial<TimelineConfig> = {}) {
    this.config = {
      duration: 10,
      frameRate: 30,
      timeUnit: 'seconds',
      snapToGrid: true,
      gridSize: 0.1,
      autoScroll: true,
      showRuler: true,
      showGrid: true,
      zoomLevel: 1,
      viewportStart: 0,
      viewportEnd: 10,
      ...config
    }

    this.state = {
      currentTime: 0,
      playbackState: 'stopped',
      loop: false,
      speed: 1,
      selectedTracks: [],
      selectedKeyframes: [],
      selectedMarkers: [],
      selectedRegions: [],
      clipboard: {
        type: 'keyframes',
        data: []
      }
    }
  }

  // 轨道管理
  addTrack(track: Omit<TimelineTrack, 'id'>, parentId?: string): TimelineTrack {
    const newTrack: TimelineTrack = {
      id: this.generateId(),
      children: [],
      visible: true,
      locked: false,
      muted: false,
      solo: false,
      state: TrackState.ACTIVE,
      color: this.generateTrackColor(),
      height: 40,
      expanded: true,
      keyframes: [],
      metadata: {},
      ...track
    }

    this.tracks.set(newTrack.id, newTrack)

    // 处理父子关系
    if (parentId && this.tracks.has(parentId)) {
      const parent = this.tracks.get(parentId)!
      parent.children.push(newTrack.id)
      newTrack.parentId = parentId
    } else {
      this.trackOrder.push(newTrack.id)
    }

    this.notifyTrackAdd(newTrack)
    return newTrack
  }

  removeTrack(trackId: string): boolean {
    const track = this.tracks.get(trackId)
    if (!track) return false

    // 递归删除子轨道
    track.children.forEach(childId => this.removeTrack(childId))

    // 从父轨道中移除
    if (track.parentId) {
      const parent = this.tracks.get(track.parentId)
      if (parent) {
        parent.children = parent.children.filter(id => id !== trackId)
      }
    } else {
      this.trackOrder = this.trackOrder.filter(id => id !== trackId)
    }

    this.tracks.delete(trackId)
    this.notifyTrackRemove(trackId)
    return true
  }

  getTrack(trackId: string): TimelineTrack | null {
    return this.tracks.get(trackId) || null
  }

  getAllTracks(): TimelineTrack[] {
    return Array.from(this.tracks.values())
  }

  getTracksByOrder(): TimelineTrack[] {
    const result: TimelineTrack[] = []
    
    const addTrackAndChildren = (trackId: string, depth = 0) => {
      const track = this.tracks.get(trackId)
      if (track) {
        result.push({ ...track, metadata: { ...track.metadata, depth } })
        track.children.forEach(childId => addTrackAndChildren(childId, depth + 1))
      }
    }

    this.trackOrder.forEach(trackId => addTrackAndChildren(trackId))
    return result
  }

  updateTrack(trackId: string, updates: Partial<TimelineTrack>): boolean {
    const track = this.tracks.get(trackId)
    if (!track) return false

    Object.assign(track, updates)
    this.notifyTrackUpdate(track)
    return true
  }

  // 关键帧管理
  addKeyframe(trackId: string, keyframe: Omit<Keyframe, 'id'>): Keyframe | null {
    const track = this.tracks.get(trackId)
    if (!track) return null

    const newKeyframe: Keyframe = {
      id: this.generateId(),
      ...keyframe
    }

    // 插入关键帧并保持时间顺序
    const insertIndex = track.keyframes.findIndex(kf => kf.time > newKeyframe.time)
    if (insertIndex === -1) {
      track.keyframes.push(newKeyframe)
    } else {
      track.keyframes.splice(insertIndex, 0, newKeyframe)
    }

    this.notifyKeyframeAdd(trackId, newKeyframe)
    return newKeyframe
  }

  removeKeyframe(trackId: string, keyframeId: string): boolean {
    const track = this.tracks.get(trackId)
    if (!track) return false

    const index = track.keyframes.findIndex(kf => kf.id === keyframeId)
    if (index === -1) return false

    track.keyframes.splice(index, 1)
    this.notifyKeyframeRemove(trackId, keyframeId)
    return true
  }

  updateKeyframe(trackId: string, keyframeId: string, updates: Partial<Keyframe>): boolean {
    const track = this.tracks.get(trackId)
    if (!track) return false

    const keyframe = track.keyframes.find(kf => kf.id === keyframeId)
    if (!keyframe) return false

    Object.assign(keyframe, updates)

    // 如果时间改变了，重新排序
    if (updates.time !== undefined) {
      track.keyframes.sort((a, b) => a.time - b.time)
    }

    this.notifyKeyframeUpdate(trackId, keyframe)
    return true
  }

  getKeyframesInRange(trackId: string, startTime: number, endTime: number): Keyframe[] {
    const track = this.tracks.get(trackId)
    if (!track) return []

    return track.keyframes.filter(kf => kf.time >= startTime && kf.time <= endTime)
  }

  // 标记管理
  addMarker(marker: Omit<TimelineMarker, 'id'>): TimelineMarker {
    const newMarker: TimelineMarker = {
      id: this.generateId(),
      metadata: {},
      ...marker
    }

    this.markers.set(newMarker.id, newMarker)
    return newMarker
  }

  removeMarker(markerId: string): boolean {
    return this.markers.delete(markerId)
  }

  getMarker(markerId: string): TimelineMarker | null {
    return this.markers.get(markerId) || null
  }

  getAllMarkers(): TimelineMarker[] {
    return Array.from(this.markers.values()).sort((a, b) => a.time - b.time)
  }

  // 区域管理
  addRegion(region: Omit<TimelineRegion, 'id'>): TimelineRegion {
    const newRegion: TimelineRegion = {
      id: this.generateId(),
      metadata: {},
      ...region
    }

    this.regions.set(newRegion.id, newRegion)
    return newRegion
  }

  removeRegion(regionId: string): boolean {
    return this.regions.delete(regionId)
  }

  getRegion(regionId: string): TimelineRegion | null {
    return this.regions.get(regionId) || null
  }

  getAllRegions(): TimelineRegion[] {
    return Array.from(this.regions.values()).sort((a, b) => a.startTime - b.startTime)
  }

  // 时间控制
  setCurrentTime(time: number) {
    const clampedTime = Math.max(0, Math.min(this.config.duration, time))
    if (this.config.snapToGrid) {
      this.state.currentTime = this.snapToGrid(clampedTime)
    } else {
      this.state.currentTime = clampedTime
    }
    this.notifyTimeChange(this.state.currentTime)
  }

  getCurrentTime(): number {
    return this.state.currentTime
  }

  // 选择管理
  selectTracks(trackIds: string[], multiSelect = false) {
    if (multiSelect) {
      this.state.selectedTracks = [...new Set([...this.state.selectedTracks, ...trackIds])]
    } else {
      this.state.selectedTracks = trackIds
    }
    this.notifySelectionChange({ tracks: this.state.selectedTracks })
  }

  selectKeyframes(keyframeIds: string[], multiSelect = false) {
    if (multiSelect) {
      this.state.selectedKeyframes = [...new Set([...this.state.selectedKeyframes, ...keyframeIds])]
    } else {
      this.state.selectedKeyframes = keyframeIds
    }
    this.notifySelectionChange({ keyframes: this.state.selectedKeyframes })
  }

  clearSelection() {
    this.state.selectedTracks = []
    this.state.selectedKeyframes = []
    this.state.selectedMarkers = []
    this.state.selectedRegions = []
    this.notifySelectionChange({})
  }

  // 工具方法
  private snapToGrid(time: number): number {
    return Math.round(time / this.config.gridSize) * this.config.gridSize
  }

  private generateId(): string {
    return `timeline_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`
  }

  private generateTrackColor(): string {
    const colors = ['#ff6b6b', '#4ecdc4', '#45b7d1', '#96ceb4', '#feca57', '#ff9ff3', '#54a0ff']
    return colors[Math.floor(Math.random() * colors.length)]
  }

  // 事件通知
  private notifyTrackAdd(track: TimelineTrack) {
    this.callbacks.onTrackAdd.forEach(callback => callback(track))
  }

  private notifyTrackRemove(trackId: string) {
    this.callbacks.onTrackRemove.forEach(callback => callback(trackId))
  }

  private notifyTrackUpdate(track: TimelineTrack) {
    this.callbacks.onTrackUpdate.forEach(callback => callback(track))
  }

  private notifyKeyframeAdd(trackId: string, keyframe: Keyframe) {
    this.callbacks.onKeyframeAdd.forEach(callback => callback(trackId, keyframe))
  }

  private notifyKeyframeRemove(trackId: string, keyframeId: string) {
    this.callbacks.onKeyframeRemove.forEach(callback => callback(trackId, keyframeId))
  }

  private notifyKeyframeUpdate(trackId: string, keyframe: Keyframe) {
    this.callbacks.onKeyframeUpdate.forEach(callback => callback(trackId, keyframe))
  }

  private notifyTimeChange(time: number) {
    this.callbacks.onTimeChange.forEach(callback => callback(time))
  }

  private notifySelectionChange(selection: any) {
    this.callbacks.onSelectionChange.forEach(callback => callback(selection))
  }

  // 事件监听
  on(event: string, callback: any) {
    if (event in this.callbacks) {
      (this.callbacks as any)[event].push(callback)
    }
  }

  off(event: string, callback: any) {
    if (event in this.callbacks) {
      const callbacks = (this.callbacks as any)[event]
      const index = callbacks.indexOf(callback)
      if (index > -1) {
        callbacks.splice(index, 1)
      }
    }
  }

  // 获取配置和状态
  getConfig(): TimelineConfig {
    return { ...this.config }
  }

  getState(): TimelineState {
    return { ...this.state }
  }

  updateConfig(updates: Partial<TimelineConfig>) {
    Object.assign(this.config, updates)
  }
}

// 导出默认时间轴管理器实例
export const defaultTimelineManager = new TimelineManager()
